home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / binutils.252 / gas / cond.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-22  |  5.4 KB  |  210 lines

  1. /* cond.c - conditional assembly pseudo-ops, and .include
  2.    Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GAS; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "as.h"
  21.  
  22. #include "obstack.h"
  23.  
  24. /* This is allocated to grow and shrink as .ifdef/.endif pairs are scanned. */
  25. struct obstack cond_obstack;
  26.  
  27. struct file_line
  28. {
  29.   char *file;
  30.   unsigned int line;
  31. };                /* file_line */
  32.  
  33. /* This is what we push and pop. */
  34. struct conditional_frame
  35.   {
  36.     struct file_line if_file_line;    /* the source file & line number of the "if" */
  37.     struct file_line else_file_line;    /* the source file & line of the "else" */
  38.     struct conditional_frame *previous_cframe;
  39.     int else_seen;        /* have we seen an else yet? */
  40.     int ignoring;        /* if we are currently ignoring input. */
  41.     int dead_tree;        /* if a conditional at a higher level is ignoring input. */
  42.   };                /* conditional_frame */
  43.  
  44. static void initialize_cframe PARAMS ((struct conditional_frame *cframe));
  45.  
  46. static struct conditional_frame *current_cframe = NULL;
  47.  
  48. void 
  49. s_ifdef (arg)
  50.      int arg;
  51. {
  52.   register char *name;        /* points to name of symbol */
  53.   register struct symbol *symbolP;    /* Points to symbol */
  54.   struct conditional_frame cframe;
  55.  
  56.   SKIP_WHITESPACE ();        /* Leading whitespace is part of operand. */
  57.   name = input_line_pointer;
  58.  
  59.   if (!is_name_beginner (*name))
  60.     {
  61.       as_bad ("invalid identifier for \".ifdef\"");
  62.       obstack_1grow (&cond_obstack, 0);
  63.     }
  64.   else
  65.     {
  66.       get_symbol_end ();
  67.       ++input_line_pointer;
  68.       symbolP = symbol_find (name);
  69.  
  70.       initialize_cframe (&cframe);
  71.       cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg);
  72.       current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe));
  73.     }                /* if a valid identifyer name */
  74.  
  75.   return;
  76. }                /* s_ifdef() */
  77.  
  78. void 
  79. s_if (arg)
  80.      int arg;
  81. {
  82.   expressionS operand;
  83.   struct conditional_frame cframe;
  84.  
  85.   SKIP_WHITESPACE ();        /* Leading whitespace is part of operand. */
  86.   expression (&operand);
  87.  
  88.   if (operand.X_op != O_constant)
  89.     as_bad ("non-constant expression in \".if\" statement");
  90.  
  91.   /* If the above error is signaled, this will dispatch
  92.      using an undefined result.  No big deal.  */
  93.   initialize_cframe (&cframe);
  94.   cframe.ignoring = cframe.dead_tree || !((operand.X_add_number != 0) ^ arg);
  95.   current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe));
  96.   return;
  97. }                /* s_if() */
  98.  
  99. void 
  100. s_endif (arg)
  101.      int arg;
  102. {
  103.   struct conditional_frame *hold;
  104.  
  105.   if (current_cframe == NULL)
  106.     {
  107.       as_bad ("\".endif\" without \".if\"");
  108.     }
  109.   else
  110.     {
  111.       hold = current_cframe;
  112.       current_cframe = current_cframe->previous_cframe;
  113.       obstack_free (&cond_obstack, hold);
  114.     }                /* if one pop too many */
  115.  
  116.   return;
  117. }                /* s_endif() */
  118.  
  119. void 
  120. s_else (arg)
  121.      int arg;
  122. {
  123.   if (current_cframe == NULL)
  124.     {
  125.       as_bad (".else without matching .if - ignored");
  126.  
  127.     }
  128.   else if (current_cframe->else_seen)
  129.     {
  130.       as_bad ("duplicate \"else\" - ignored");
  131.       as_bad_where (current_cframe->else_file_line.file,
  132.             current_cframe->else_file_line.line,
  133.             "here is the previous \"else\"");
  134.       as_bad_where (current_cframe->if_file_line.file,
  135.             current_cframe->if_file_line.line,
  136.             "here is the previous \"if\"");
  137.     }
  138.   else
  139.     {
  140.       as_where (¤t_cframe->else_file_line.file,
  141.         ¤t_cframe->else_file_line.line);
  142.  
  143.       if (!current_cframe->dead_tree)
  144.     {
  145.       current_cframe->ignoring = !current_cframe->ignoring;
  146.     }            /* if not a dead tree */
  147.  
  148.       current_cframe->else_seen = 1;
  149.     }                /* if error else do it */
  150.  
  151.   return;
  152. }                /* s_else() */
  153.  
  154. void 
  155. s_ifeqs (arg)
  156.      int arg;
  157. {
  158.   as_bad ("ifeqs not implemented.");
  159.  
  160.   return;
  161. }                /* s_ifeqs() */
  162.  
  163. void 
  164. s_end (arg)
  165.      int arg;
  166. {
  167.   return;
  168. }                /* s_end() */
  169.  
  170. int 
  171. ignore_input ()
  172. {
  173.   /* We cannot ignore certain pseudo ops.  */
  174.   if (input_line_pointer[-1] == '.'
  175.       && ((input_line_pointer[0] == 'i'
  176.        && (!strncmp (input_line_pointer, "if", 2)
  177.            || !strncmp (input_line_pointer, "ifdef", 5)
  178.            || !strncmp (input_line_pointer, "ifndef", 6)))
  179.       || (input_line_pointer[0] == 'e'
  180.           && (!strncmp (input_line_pointer, "else", 4)
  181.           || !strncmp (input_line_pointer, "endif", 5)))))
  182.     {
  183.       return 0;
  184.     }
  185.  
  186.   return ((current_cframe != NULL) && (current_cframe->ignoring));
  187. }                /* ignore_input() */
  188.  
  189. static void 
  190. initialize_cframe (cframe)
  191.      struct conditional_frame *cframe;
  192. {
  193.   memset (cframe, 0, sizeof (*cframe));
  194.   as_where (&cframe->if_file_line.file,
  195.         &cframe->if_file_line.line);
  196.   cframe->previous_cframe = current_cframe;
  197.   cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring;
  198.  
  199.   return;
  200. }                /* initialize_cframe() */
  201.  
  202. /*
  203.  * Local Variables:
  204.  * fill-column: 131
  205.  * comment-column: 0
  206.  * End:
  207.  */
  208.  
  209. /* end of cond.c */
  210.